import 'package:json_annotation/json_annotation.dart';

part 'book.g.dart';

@JsonSerializable()
class Book {
  final String id;
  final String title;
  final String author;
  final String description;
  final String isbn;
  final double price;
  final String coverImageUrl;
  final String category;
  final double rating;
  final int reviewCount;
  final int stock;
  final DateTime publishedDate;
  final List<String> tags;
  final String publisher;
  final int pageCount;
  final String language;

  const Book({
    required this.id,
    required this.title,
    required this.author,
    required this.description,
    required this.isbn,
    required this.price,
    required this.coverImageUrl,
    required this.category,
    required this.rating,
    required this.reviewCount,
    required this.stock,
    required this.publishedDate,
    required this.tags,
    required this.publisher,
    required this.pageCount,
    required this.language,
  });

  factory Book.fromJson(Map<String, dynamic> json) => _$BookFromJson(json);
  Map<String, dynamic> toJson() => _$BookToJson(this);

  Book copyWith({
    String? id,
    String? title,
    String? author,
    String? description,
    String? isbn,
    double? price,
    String? coverImageUrl,
    String? category,
    double? rating,
    int? reviewCount,
    int? stock,
    DateTime? publishedDate,
    List<String>? tags,
    String? publisher,
    int? pageCount,
    String? language,
  }) {
    return Book(
      id: id ?? this.id,
      title: title ?? this.title,
      author: author ?? this.author,
      description: description ?? this.description,
      isbn: isbn ?? this.isbn,
      price: price ?? this.price,
      coverImageUrl: coverImageUrl ?? this.coverImageUrl,
      category: category ?? this.category,
      rating: rating ?? this.rating,
      reviewCount: reviewCount ?? this.reviewCount,
      stock: stock ?? this.stock,
      publishedDate: publishedDate ?? this.publishedDate,
      tags: tags ?? this.tags,
      publisher: publisher ?? this.publisher,
      pageCount: pageCount ?? this.pageCount,
      language: language ?? this.language,
    );
  }

  bool get isInStock => stock > 0;
  bool get isLowStock => stock > 0 && stock <= 5;
  
  String get formattedPrice => '\$${price.toStringAsFixed(2)}';
  String get formattedRating => rating.toStringAsFixed(1);
  String get formattedReviewCount => '$reviewCount reviews';
}
